/**
 * WordPress WooCommerce通用爬虫核心类
 *
 * 主要功能：
 * - 爬取WordPress + WooCommerce电商网站的商品数据
 * - 支持简单产品和可变产品的解析
 * - 导出为WordPress WooCommerce标准导入格式的CSV文件
 * - 包含防封禁机制、错误重试和进度监控
 *
 * @class WordPressWooCommerceCrawler
 * @version 1.0.0
 * @author 项目开发者
 */

// 引入必要的依赖库
const axios = require('axios');           // HTTP请求库，用于发送网络请求
const cheerio = require('cheerio');       // HTML解析库，类似jQuery的DOM操作
const fs = require('fs');                 // 文件系统模块，用于文件读写操作
const path = require('path');             // 路径处理模块，用于文件路径操作
const { stringify } = require('csv-stringify');  // CSV生成库，用于创建CSV文件
const config = require('./config');       // 配置文件，包含所有可配置参数

class WordPressWooCommerceCrawler {
    /**
     * 爬虫类构造函数
     * 初始化爬虫实例，设置配置、数据存储和HTTP客户端
     */
    constructor() {
        // 存储配置信息
        this.config = config;
        
        // 数据存储和统计
        this.products = [];           // 存储所有爬取的商品数据（包括父产品和变体）
        this.productCount = 0;        // 已爬取的商品总数计数
        this.errorCount = 0;          // 遇到的错误数量计数
        
        /**
         * 创建自定义axios实例，配置HTTP请求参数
         * 设置请求头、超时时间等，模拟真实浏览器行为
         */
        this.axiosInstance = axios.create({
            headers: {
                'User-Agent': this.config.REQUEST_CONFIG.USER_AGENT,      // 用户代理，模拟浏览器
                'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
                'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',             // 语言偏好
                'Accept-Encoding': 'gzip, deflate, br',                   // 支持的编码格式
                'Connection': 'keep-alive',                               // 保持连接
            },
            timeout: this.config.REQUEST_CONFIG.TIMEOUT,                  // 请求超时时间（毫秒）
        });
        
        // 初始化输出目录
        this.ensureOutputDir();
        
        // 输出初始化信息
        console.log('WordPress WooCommerce爬虫初始化完成');
        console.log(`目标网站: ${this.config.TARGET_SITE.CATEGORY_URL}`);
        console.log(`最大爬取数量: ${this.config.CRAWL_LIMITS.MAX_PRODUCTS === 0 ? '无限制' : this.config.CRAWL_LIMITS.MAX_PRODUCTS}`);
    }

    /**
     * 确保输出目录存在
     * 如果输出目录不存在，则自动创建
     *
     * @returns {String} 输出目录路径
     */
    ensureOutputDir() {
        const outputDir = this.config.CSV_EXPORT.OUTPUT_DIR;
        if (!fs.existsSync(outputDir)) {
            fs.mkdirSync(outputDir, { recursive: true });  // 递归创建目录
            console.log(`创建输出目录: ${outputDir}`);
        }
        return outputDir;
    }

    /**
     * 生成随机延迟时间 - 防封禁机制核心
     * 在指定的延迟范围内生成随机毫秒数，避免请求过于频繁
     *
     * @param {Array} delayRange - 延迟范围数组 [最小值, 最大值]（毫秒）
     * @returns {Number} 随机延迟毫秒数，如果延迟禁用则返回0
     */
    getRandomDelay(delayRange) {
        // 检查是否启用延迟
        if (!this.config.DELAY_CONFIG.ENABLED) return 0;
        
        // 解构延迟范围
        const [min, max] = delayRange;
        // 生成指定范围内的随机整数
        return Math.floor(Math.random() * (max - min + 1)) + min;
    }

    /**
     * 异步延迟函数
     * 使用Promise和setTimeout实现异步等待
     *
     * @param {Number} ms - 要延迟的毫秒数
     * @returns {Promise} 延迟结束后解析的Promise
     */
    async delay(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
    }

    /**
     * 带重试机制的HTTP请求
     * 在请求失败时自动重试，提高爬虫的稳定性
     *
     * @param {String} url - 要请求的URL
     * @param {Number} retryCount - 当前重试次数（内部使用）
     * @returns {Object} axios响应对象
     * @throws {Error} 当达到最大重试次数时抛出错误
     */
    async fetchWithRetry(url, retryCount = 0) {
        try {
            // 发送HTTP GET请求
            const response = await this.axiosInstance.get(url);
            return response;
        } catch (error) {
            // 检查是否还可以重试
            if (retryCount < this.config.REQUEST_CONFIG.RETRY_COUNT) {
                console.warn(`请求失败，第${retryCount + 1}次重试: ${url}`);
                // 等待重试延迟时间
                await this.delay(this.config.REQUEST_CONFIG.RETRY_DELAY);
                // 递归调用自身进行重试
                return this.fetchWithRetry(url, retryCount + 1);
            } else {
                // 达到最大重试次数，抛出错误
                throw new Error(`请求失败: ${url} - ${error.message}`);
            }
        }
    }

    /**
     * 从分类URL中提取分类名称
     * 从URL路径中解析出分类slug，用于生成文件名
     *
     * @param {String} categoryUrl - 分类页面的完整URL
     * @returns {String} 提取的分类名称，如果提取失败则返回'products'
     */
    extractCategoryName(categoryUrl) {
        try {
            // 解析URL获取路径部分
            const url = new URL(categoryUrl);
            const pathSegments = url.pathname.split('/').filter(segment => segment);
            
            // 查找WordPress WooCommerce标准的分类路径段 'product-category'
            const categoryIndex = pathSegments.indexOf('product-category');
            if (categoryIndex !== -1 && pathSegments[categoryIndex + 1]) {
                return pathSegments[categoryIndex + 1];  // 返回分类slug
            }
            
            // 如果没有找到标准分类路径，使用最后一个非空路径段
            const lastSegment = pathSegments[pathSegments.length - 1];
            return lastSegment || 'products';  // 默认返回'products'
        } catch (error) {
            console.warn(`无法从URL提取分类名称: ${categoryUrl}`, error.message);
            return 'products';  // 错误时返回默认值
        }
    }

    /**
     * 生成包含北京时区时间戳的CSV文件名
     * 格式：分类_年-月-日+星期几缩写+时_分_秒.csv
     *
     * @param {String} categoryName - 分类名称，从URL中提取
     * @returns {String} 生成的文件名
     */
    generateFilename(categoryName) {
        // 创建北京时区时间对象（UTC+8）
        const now = new Date();
        const beijingTime = new Date(now.getTime() + (8 * 60 * 60 * 1000)); // 添加8小时转换为北京时区
        
        // 提取日期组件
        const year = beijingTime.getUTCFullYear();
        const month = String(beijingTime.getUTCMonth() + 1).padStart(2, '0');  // 月份从0开始，需要+1
        const day = String(beijingTime.getUTCDate()).padStart(2, '0');
        
        // 获取星期几的英文缩写（0=周日, 1=周一, ... 6=周六）
        const dayOfWeek = beijingTime.getUTCDay();
        const weekDays = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
        const dayAbbreviation = weekDays[dayOfWeek];
        
        // 提取时间组件
        const hours = String(beijingTime.getUTCHours()).padStart(2, '0');
        const minutes = String(beijingTime.getUTCMinutes()).padStart(2, '0');
        const seconds = String(beijingTime.getUTCSeconds()).padStart(2, '0');
        
        // 构建文件名格式：分类_年-月-日+星期几缩写+时_分_秒.csv
        return `${categoryName}_${year}-${month}-${day}+${dayAbbreviation}+${hours}_${minutes}_${seconds}.csv`;
    }

    /**
     * 从分类页面提取所有商品链接
     * 使用配置的CSS选择器从分类页面中提取商品详情页链接
     *
     * @param {String} categoryUrl - 分类页面的URL
     * @returns {Array} 商品链接数组，已去重
     */
    async extractProductLinks(categoryUrl) {
        try {
            console.log(`正在提取商品链接: ${categoryUrl}`);
            // 发送HTTP请求获取分类页面HTML
            const response = await this.fetchWithRetry(categoryUrl);
            // 使用cheerio加载HTML，提供类jQuery的DOM操作
            const $ = cheerio.load(response.data);

            const productLinks = [];
            
            /**
             * 使用配置的选择器遍历所有商品链接元素
             * 通常选择器为：'li.product a.woocommerce-LoopProduct-link'
             */
            $(this.config.TARGET_SITE.PRODUCT_LINK_SELECTOR).each((index, element) => {
                let href = $(element).attr('href');
                if (href) {
                    // 处理相对路径：如果链接以'/'开头，转换为绝对URL
                    if (href.startsWith('/')) {
                        href = new URL(href, this.config.TARGET_SITE.BASE_URL || categoryUrl).href;
                    }
                    // 只保留商品页面链接：过滤包含'/product/'的链接
                    if (href.includes('/product/')) {
                        productLinks.push(href);
                    }
                }
            });

            console.log(`找到 ${productLinks.length} 个商品链接`);
            return [...new Set(productLinks)]; // 使用Set去重后返回数组
        } catch (error) {
            console.error(`提取商品链接失败: ${categoryUrl}`, error.message);
            return []; // 错误时返回空数组
        }
    }

    /**
     * 检查当前页面是否有下一页
     * 查找分页控件中的"下一页"链接
     *
     * @param {String} currentUrl - 当前页面的URL
     * @returns {String|null} 下一页URL，如果没有下一页则返回null
     */
    async hasNextPage(currentUrl) {
        try {
            const response = await this.fetchWithRetry(currentUrl);
            const $ = cheerio.load(response.data);

            // 使用配置的选择器查找下一页链接
            // 常见选择器：'a.next.page-numbers', '.woocommerce-pagination a.next', 'a.next'
            const nextLink = $(this.config.TARGET_SITE.NEXT_PAGE_SELECTOR).attr('href');
            
            if (nextLink) {
                // 处理相对路径：转换为绝对URL
                if (nextLink.startsWith('/')) {
                    return new URL(nextLink, this.config.TARGET_SITE.BASE_URL || currentUrl).href;
                }
                return nextLink;
            }
            
            return null; // 没有找到下一页链接
        } catch (error) {
            console.error('检查下一页失败:', error.message);
            return null; // 错误时返回null
        }
    }

    /**
     * 从价格文本中提取数字并格式化
     * 处理价格字符串，提取数字部分并格式化为两位小数
     *
     * @param {String} priceText - 价格文本（可能包含货币符号等非数字字符）
     * @returns {String} 格式化后的价格数字字符串（两位小数），如果无法提取则返回空字符串
     */
    extractPriceNumber(priceText) {
        if (!priceText) return '';
        // 使用正则表达式匹配数字和可选的小数点
        // 匹配模式：一个或多个数字，可选的小数点和零个或多个数字
        const match = priceText.match(/(\d+\.?\d*)/);
        if (!match) return '';
        
        // 将匹配的数字字符串转换为浮点数
        let price = parseFloat(match[1]);
        // 确保价格是有效数字并且精确到小数点后两位
        if (!isNaN(price)) {
            return price.toFixed(2); // 格式化为两位小数
        }
        return '';
    }

    /**
     * 解析商品详情页面
     * @param {String} productUrl - 商品页面URL
     * @returns {Array|null} 商品数据对象数组（父产品 + 变体）或null
     */
    async parseProductPage(productUrl) {
        try {
            console.log(`正在解析商品页面: ${productUrl}`);
            const response = await this.fetchWithRetry(productUrl);
            const $ = cheerio.load(response.data);

            // 提取商品标题
            const productName = $(this.config.DATA_EXTRACTION.TITLE_SELECTOR).first().text().trim();

            // 提取SKU - 从商品页面的表单中查找
            let sku = '';
            
            // 方法1: 从添加到购物车按钮的data-product_sku属性中查找
            sku = $('.add_to_cart_button').attr('data-product_sku') || '';
            
            // 方法2: 从表单中的隐藏字段查找
            if (!sku) {
                sku = $('input[name="add-to-cart"]').attr('data-product_sku') || '';
            }
            
            // 方法3: 从页面中查找SKU元素
            if (!sku) {
                sku = $(this.config.DATA_EXTRACTION.SKU_SELECTOR).first().text().trim();
            }
            
            // 方法4: 从URL生成SKU
            if (!sku) {
                const urlMatch = productUrl.match(/product\/([^\/]+)/);
                if (urlMatch) {
                    sku = urlMatch[1];
                }
            }
            
            // 方法5: 基于标题生成唯一SKU
            if (!sku && productName) {
                sku = productName.toLowerCase()
                    .replace(/[^a-z0-9]/g, '-')
                    .replace(/-+/g, '-')
                    .replace(/^-|-$/g, '')
                    .substring(0, 30);
                
                // 添加时间戳确保唯一性
                sku += '-' + Date.now().toString().slice(-6);
            }
            
            // 确保SKU不为空且不是"Add to cart"
            if (!sku || sku === 'Add to cart' || sku === 'Select options') {
                // 生成基于URL和时间的唯一SKU
                const urlSlug = productUrl.split('/').filter(Boolean).pop();
                sku = 'SKU-' + urlSlug + '-' + Date.now().toString().slice(-6);
            }

            // 提取价格信息 - 根据网页源代码重新设计价格提取逻辑
            const $priceElement = $('.price').first();
            let regularPriceText = '';
            let salePriceText = '';

            // 检查是否有折扣价（有del和ins标签的情况）
            const $delElement = $priceElement.find('del .woocommerce-Price-amount');
            const $insElement = $priceElement.find('ins .woocommerce-Price-amount');
            
            if ($delElement.length > 0 && $insElement.length > 0) {
                // 有折扣情况：del标签是原价，ins标签是促销价
                regularPriceText = $delElement.first().text().trim();
                salePriceText = $insElement.first().text().trim();
            } else {
                // 没有折扣情况：直接提取价格
                const $normalPriceElement = $priceElement.find('.woocommerce-Price-amount').first();
                if ($normalPriceElement.length > 0) {
                    regularPriceText = $normalPriceElement.text().trim();
                }
            }

            const regularPrice = this.extractPriceNumber(regularPriceText);
            const salePrice = this.extractPriceNumber(salePriceText);

            // 提取商品描述
            const description = $(this.config.DATA_EXTRACTION.DESCRIPTION_SELECTOR).first().text().trim();
            const shortDescription = description ? description.substring(0, 200) : '';

            // 提取商品图片
            const imageUrls = [];
            $(this.config.DATA_EXTRACTION.IMAGE_SELECTOR).each((index, element) => {
                let imgSrc = $(element).attr('src');
                if (imgSrc) {
                    // 处理相对路径
                    if (imgSrc.startsWith('/')) {
                        imgSrc = new URL(imgSrc, this.config.TARGET_SITE.BASE_URL || productUrl).href;
                    }
                    // 确保是完整的URL
                    if (imgSrc.startsWith('http') && !imageUrls.includes(imgSrc)) {
                        imageUrls.push(imgSrc);
                    }
                }
            });
            const images = imageUrls.join(', ');

            // 提取分类信息
            const categories = [];
            $(this.config.DATA_EXTRACTION.CATEGORY_SELECTOR).each((index, element) => {
                const category = $(element).text().trim();
                if (category && !categories.includes(category)) {
                    categories.push(category);
                }
            });
            const categoryList = categories.join(', ');

            // 提取属性信息（用于变体产品）
            const attributes = {};
            
            // 查找属性表格行
            $('table.variations tr').each((index, element) => {
                const $row = $(element);
                let label = $row.find('th.label label').text().trim();
                const values = [];
                
                // 提取属性值
                $row.find('.ast-single-variation').each((i, el) => {
                    const value = $(el).text().trim();
                    if (value) {
                        values.push(value);
                    }
                });
                
                // 如果通过按钮没有找到值，尝试从select元素中提取
                if (values.length === 0) {
                    $row.find('select option').each((i, el) => {
                        const value = $(el).text().trim();
                        if (value && value !== 'Choose an option') {
                            values.push(value);
                        }
                    });
                }
                
                if (label && values.length > 0) {
                    // 避免使用WordPress保留术语"name"
                    if (label.toLowerCase() === 'name') {
                        label = 'Player Name'; // 改为非保留术语
                    }
                    attributes[label] = values;
                }
            });

            const attributeNames = Object.keys(attributes);
            const products = [];

            if (attributeNames.length > 0) {
                // 创建父产品（可变产品）
                const parentProduct = this.createProductTemplate();
                parentProduct['Type'] = 'variable';
                parentProduct['SKU'] = sku;
                parentProduct['Name'] = productName;
                parentProduct['Short description'] = shortDescription;
                parentProduct['Description'] = description;
                parentProduct['Regular price'] = regularPrice;
                parentProduct['Sale price'] = salePrice;
                parentProduct['Images'] = images;
                parentProduct['Categories'] = categoryList;
                
                // 设置属性 - 父产品列出所有可能的属性值
                if (attributeNames.length >= 1) {
                    const firstAttrName = attributeNames[0];
                    parentProduct['Attribute 1 name'] = firstAttrName;
                    parentProduct['Attribute 1 value(s)'] = attributes[firstAttrName].join(', ');
                    // 父产品的属性可见性设置为1（可见）和1（全局属性）
                    parentProduct['Attribute 1 visible'] = '1';
                    parentProduct['Attribute 1 global'] = '1';
                }
                
                if (attributeNames.length >= 2) {
                    const secondAttrName = attributeNames[1];
                    parentProduct['Attribute 2 name'] = secondAttrName;
                    parentProduct['Attribute 2 value(s)'] = attributes[secondAttrName].join(', ');
                    // 父产品的属性可见性设置为1（可见）和1（全局属性）
                    parentProduct['Attribute 2 visible'] = '1';
                    parentProduct['Attribute 2 global'] = '1';
                }

                products.push(parentProduct);

                // 生成所有属性组合的变体
                const variations = this.generateVariations(parentProduct, attributes, sku);
                products.push(...variations);

                console.log(`成功解析可变商品: ${productName} (${attributeNames.length} 个属性, ${variations.length} 个变体)`);
            } else {
                // 简单产品
                const simpleProduct = this.createProductTemplate();
                simpleProduct['Type'] = 'simple';
                simpleProduct['SKU'] = sku;
                simpleProduct['Name'] = productName;
                simpleProduct['Short description'] = shortDescription;
                simpleProduct['Description'] = description;
                simpleProduct['Regular price'] = regularPrice;
                simpleProduct['Sale price'] = salePrice;
                simpleProduct['Images'] = images;
                simpleProduct['Categories'] = categoryList;
                products.push(simpleProduct);

                console.log(`成功解析简单商品: ${productName}`);
            }

            return products;

        } catch (error) {
            console.error(`解析商品页面失败: ${productUrl}`, error.message);
            this.errorCount++;
            return null;
        }
    }

    /**
     * 创建基础产品模板
     * @returns {Object} 基础产品对象
     */
    createProductTemplate() {
        return {
            // 基本信息
            'ID': '', // 留空，WordPress会自动生成
            'Type': 'simple',
            'SKU': '',
            'Name': '',
            'Published': '1', // 发布状态
            'Is featured?': '0', // 是否特色产品
            'Visibility in catalog': 'visible', // 可见性
            'Short description': '',
            'Description': '',
            'Date sale price starts': '',
            'Date sale price ends': '',
            'Tax status': 'taxable', // 税收状态
            'Tax class': '', // 税类
            'In stock?': '1', // 是否有库存
            'Stock': '100', // 库存数量
            'Low stock amount': '',
            'Backorders allowed?': '0', // 是否允许缺货订购
            'Sold individually?': '0', // 是否单独销售
            'Weight (kg)': '',
            'Length (cm)': '',
            'Width (cm)': '',
            'Height (cm)': '',
            'Allow customer reviews?': '1', // 允许评论
            'Purchase note': '',
            'Sale price': '',
            'Regular price': '',
            'Categories': '',
            'Tags': '',
            'Shipping class': '',
            'Images': '',
            'Download limit': '',
            'Download expiry days': '',
            'Parent': '',
            'Grouped products': '',
            'Upsells': '',
            'Cross-sells': '',
            'External URL': '',
            'Button text': '',
            'Position': '0',
            'Attribute 1 name': '',
            'Attribute 1 value(s)': '',
            'Attribute 1 visible': '1',
            'Attribute 1 global': '1',
            'Attribute 2 name': '',
            'Attribute 2 value(s)': '',
            'Attribute 2 visible': '1',
            'Attribute 2 global': '1'
        };
    }

    /**
     * 生成所有属性组合的变体
     * @param {Object} parentProduct - 父产品
     * @param {Object} attributes - 属性对象
     * @param {String} parentSku - 父产品SKU
     * @returns {Array} 变体产品数组
     */
    generateVariations(parentProduct, attributes, parentSku) {
        const variations = [];
        const attributeNames = Object.keys(attributes);
        
        if (attributeNames.length === 0) return variations;

        // 生成属性值的笛卡尔积
        const attributeValues = attributeNames.map(name => attributes[name]);
        const combinations = this.cartesianProduct(...attributeValues);

        combinations.forEach((combination, index) => {
            const variation = this.createProductTemplate();
            variation['Type'] = 'variation';
            // 变体产品的Visibility跟随父产品
            variation['Visibility in catalog'] = parentProduct['Visibility in catalog'];
            variation['Parent'] = parentSku; // 设置父产品SKU
            
            // 优化变体SKU和名称生成 - 更简洁的格式
            const variationNumber = index + 1;
            variation['SKU'] = `${parentSku}-${variationNumber}`;
            variation['Name'] = `${parentProduct['Name']} - ${combination.join(', ')}`;
            
            // 继承父产品的价格
            variation['Regular price'] = parentProduct['Regular price'];
            variation['Sale price'] = parentProduct['Sale price'];
            
            // 设置变体的具体属性值
            combination.forEach((value, attrIndex) => {
                const attrName = attributeNames[attrIndex];
                if (attrIndex === 0) {
                    variation['Attribute 1 name'] = attrName;
                    variation['Attribute 1 value(s)'] = value;
                    // 变体产品的属性可见性字段为空
                    variation['Attribute 1 visible'] = '';
                    // 变体产品的Attribute global跟随父产品
                    variation['Attribute 1 global'] = parentProduct['Attribute 1 global'];
                } else if (attrIndex === 1) {
                    variation['Attribute 2 name'] = attrName;
                    variation['Attribute 2 value(s)'] = value;
                    // 变体产品的属性可见性字段为空
                    variation['Attribute 2 visible'] = '';
                    // 变体产品的Attribute global跟随父产品
                    variation['Attribute 2 global'] = parentProduct['Attribute 2 global'];
                }
            });

            variations.push(variation);
        });

        return variations;
    }

    /**
     * 计算多个数组的笛卡尔积
     * @param {...Array} arrays - 输入数组
     * @returns {Array} 笛卡尔积结果
     */
    cartesianProduct(...arrays) {
        return arrays.reduce((acc, curr) => {
            return acc.flatMap(x => curr.map(y => [...x, y]));
        }, [[]]);
    }

    /**
     * 爬取整个分类的商品
     * @param {String} categoryUrl - 分类URL
     */
    async crawlCategory(categoryUrl) {
        let currentPage = categoryUrl;
        let pageCount = 1;
        let parentProductCount = 0; // 父产品计数器

        console.log(`开始爬取分类: ${categoryUrl}`);

        while (currentPage &&
               (this.config.CRAWL_LIMITS.MAX_PAGES === 0 || pageCount <= this.config.CRAWL_LIMITS.MAX_PAGES) &&
               (this.config.CRAWL_LIMITS.MAX_PRODUCTS === 0 || parentProductCount < this.config.CRAWL_LIMITS.MAX_PRODUCTS)) {
            
            console.log(`正在处理第 ${pageCount} 页: ${currentPage}`);
            
            // 提取当前页面的商品链接
            const productLinks = await this.extractProductLinks(currentPage);
            
            if (productLinks.length === 0) {
                console.log('没有找到商品链接，可能已到达最后一页');
                break;
            }

            // 处理每个商品链接
            for (const link of productLinks) {
                // 检查是否达到最大父产品数量限制
                if (this.config.CRAWL_LIMITS.MAX_PRODUCTS > 0 &&
                    parentProductCount >= this.config.CRAWL_LIMITS.MAX_PRODUCTS) {
                    console.log(`已达到最大父产品数量限制: ${this.config.CRAWL_LIMITS.MAX_PRODUCTS}`);
                    break;
                }

                // 检查错误数量限制
                if (this.errorCount >= this.config.ERROR_HANDLING.MAX_ERRORS) {
                    console.log(`达到最大错误数量限制: ${this.config.ERROR_HANDLING.MAX_ERRORS}`);
                    break;
                }

                if (this.config.CRAWL_LIMITS.DEEP_CRAWL) {
                    const products = await this.parseProductPage(link);
                    if (products && products.length > 0) {
                        // 计算父产品数量
                        const parentProducts = products.filter(p => p.Type === 'variable' || p.Type === 'simple');
                        parentProductCount += parentProducts.length;
                        
                        // 添加所有产品（父产品和变体）
                        this.products.push(...products);
                        this.productCount += products.length;
                        
                        console.log(`成功添加商品: ${parentProducts.length} 个父产品, ${products.length - parentProducts.length} 个变体`);
                    }
                } else {
                    // 浅度爬取，只收集链接
                    this.products.push({ 'Name': '待解析', 'SKU': link });
                    this.productCount++;
                    parentProductCount++;
                }

                // 商品页面随机延迟
                const productDelay = this.getRandomDelay(this.config.DELAY_CONFIG.PRODUCT_PAGE);
                await this.delay(productDelay);
            }

            // 检查是否有下一页
            const nextPage = await this.hasNextPage(currentPage);
            if (nextPage &&
                (this.config.CRAWL_LIMITS.MAX_PRODUCTS === 0 || parentProductCount < this.config.CRAWL_LIMITS.MAX_PRODUCTS)) {
                currentPage = nextPage;
                pageCount++;
                
                // 翻页随机延迟
                const pageDelay = this.getRandomDelay(this.config.DELAY_CONFIG.NEXT_PAGE);
                await this.delay(pageDelay);
            } else {
                currentPage = null;
            }
        }

        console.log(`分类爬取完成! 总共获取了 ${parentProductCount} 个父产品, ${this.products.length} 个总产品`);
    }

    /**
     * 导出为WordPress导入格式的CSV文件
     * @returns {String} 导出的文件路径
     */
    async exportToCSV() {
        if (this.products.length === 0) {
            console.log('没有商品数据可导出');
            return null;
        }

        const categoryName = this.extractCategoryName(this.config.TARGET_SITE.CATEGORY_URL);
        const filename = this.generateFilename(categoryName);
        const filePath = path.join(this.config.CSV_EXPORT.OUTPUT_DIR, filename);

        // 定义CSV列头，按照WordPress导入格式
        const columns = [
            'ID', 'Type', 'SKU', 'Name', 'Published', 'Is featured?', 'Visibility in catalog',
            'Short description', 'Description', 'Date sale price starts', 'Date sale price ends',
            'Tax status', 'Tax class', 'In stock?', 'Stock', 'Low stock amount', 'Backorders allowed?',
            'Sold individually?', 'Weight (kg)', 'Length (cm)', 'Width (cm)', 'Height (cm)',
            'Allow customer reviews?', 'Purchase note', 'Sale price', 'Regular price', 'Categories',
            'Tags', 'Shipping class', 'Images', 'Download limit', 'Download expiry days', 'Parent',
            'Grouped products', 'Upsells', 'Cross-sells', 'External URL', 'Button text', 'Position',
            'Attribute 1 name', 'Attribute 1 value(s)', 'Attribute 1 visible', 'Attribute 1 global',
            'Attribute 2 name', 'Attribute 2 value(s)', 'Attribute 2 visible', 'Attribute 2 global'
        ];

        // 构建CSV内容
        let csvContent = '';
        
        // 添加BOM头解决中文Excel乱码问题
        if (this.config.CSV_EXPORT.INCLUDE_BOM) {
            csvContent += '\uFEFF';
        }
        
        // 添加表头
        csvContent += columns.map(col => `"${col}"`).join(',') + '\n';
        
        // 添加数据行
        this.products.forEach(product => {
            const row = columns.map(column => {
                let value = product[column] || '';
                // 处理CSV转义：将双引号转义为两个双引号，并用双引号包围字段
                value = value.toString().replace(/"/g, '""');
                return `"${value}"`;
            });
            csvContent += row.join(',') + '\n';
        });

        fs.writeFileSync(filePath, csvContent, this.config.CSV_EXPORT.ENCODING);
        console.log(`WordPress导入CSV文件已导出: ${filePath}`);
        console.log(`总共导出 ${this.products.length} 个商品`);

        return filePath;
    }

    /**
     * 主运行函数
     */
    async run() {
        try {
            console.log('=== WordPress WooCommerce爬虫开始运行 ===');
            const startTime = Date.now();

            await this.crawlCategory(this.config.TARGET_SITE.CATEGORY_URL);
            const filePath = await this.exportToCSV();

            const endTime = Date.now();
            const duration = ((endTime - startTime) / 1000).toFixed(2);
            
            console.log('=== 爬虫任务完成 ===');
            console.log(`总耗时: ${duration} 秒`);
            console.log(`成功爬取: ${this.products.length} 个商品`);
            console.log(`遇到错误: ${this.errorCount} 次`);
            
            if (filePath) {
                console.log(`CSV文件位置: ${filePath}`);
            }

            return {
                success: true,
                productCount: this.products.length,
                errorCount: this.errorCount,
                filePath: filePath,
                duration: duration
            };

        } catch (error) {
            console.error('爬虫运行失败:', error);
            return {
                success: false,
                error: error.message,
                productCount: this.products.length,
                errorCount: this.errorCount
            };
        }
    }
}

module.exports = WordPressWooCommerceCrawler;